/**
 * Created by sjg on 2017/8/8.
 */

var ItbItemsModel = require('../../../common/mysql/mapping/ItbItemsModel');
var TgUserDocModel = require('../../../common/mysql/mapping/TgUserDocModel');
var ItbActivityModel = require('../../../common/mysql/mapping/ItbActivityModel');
var ItbActivityRModel = require('../../../common/mysql/mapping/ItbActivityRModel');
var ItbTradeOrderModel = require('../../../common/mysql/mapping/ItbTradeOrderModel');
var ItbTradeOrderDetailModel = require('../../../common/mysql/mapping/ItbTradeOrderDetailModel');
var ItbCouponModel = require('../../../common/mysql/mapping/ItbCouponModel');
var ItbQtyPriceModel = require('../../../common/mysql/mapping/ItbQtyPriceModel');

var CommonUtil = require('../../../common/util/CommonUtil');
var CONFIG = require('../../../common/config');

var payUtil = require('../util/payUtil');
var printUtil = require('../util/printUtil');
var luaUtil = require('../util/luaUtil');

var moment = require('moment');  // 日期格式化
var async = require('async');
var superagent = require('superagent');
var nodemailer = require('nodemailer');
var SJGTGV3 = require('./../../sjg/common/tg3/SJGTGV3');


// var Mongo = require('../../../common/mongo');
// var MAPILogSummaryModel = Mongo.MAPILogSummaryModel;
// var MAPILogModel = Mongo.MAPILogModel;



var summaryUtil = (function(){

    function summaryUtil() {
    }
    //--------------------------------------------------------------------------------------------

    //------------------------------------------------------------------
    // 返回json
    summaryUtil.ret_func_json = function (success, msg, data, res){
        var obj = {
            success: success,
            msg: msg,
            data: data
        };
        // 返回
        res.set('Content-Type', 'application/json');
        res.json(obj);
    };

    //------------------------------------------------------------------
    // 功能：从APILog统计一个时间段（目前按一小时一次）的数据
    // 参数：startTime，开始时间，例如：'2015-08-01 00:00:00'
    // 参数：endTime，结束时间，例如：'2015-08-01 01:00:00'
    summaryUtil.summaryOnePeriodFromAPILog = function(startDate, endDate, callback) {
        // 返回ab中较大的（如果a不存在，则返回b）
        function func_lt(a,b){
            if(!a)  return b;
            return a<b?a:b;
        }
        // 返回ab中较小的（如果a不存在，则返回b）
        function func_gt(a,b){
            if(!a)  return b;
            return a>b?a:b;
        }
        // 从对象中遍历key
        function func_enum(obj){
            var ret = [];
            for(var i in obj){
                var one = obj[i];
                if(typeof one !='function'){
                   ret.push(i);
                }
            }
            return ret;
        }
        // t2-t1，返回秒
        function func_minus_time(t1,t2){
            var date1 = new Date(t1)
            var date2 = new Date(t2);

            var s1 = date1.getTime(),s2 = date2.getTime();
            var total = (s2 - s1)/1000;
            return total
        }
        // 处理一页
        // 参数：callback，回调，参数如下：
        //              error:
        //              data:{
        //                  id_start
        //                  id_end
        //                  user_map:{ USER_ID:{count:1,start_time:'',end_time:''} }
        //                  api_map:{ API_NAME:{count:1,start_time:'',end_time:''} }
        //                  device:[]
        //              }
        function processOnePage(items, callback){
            var data = {id_start:null, id_end:null, user_map:{}, api_map:{} , device:[]};
            for(var i=0;i<items.length;i++){
                var one = items[i];
                var _id = one._id;
                var createdAt = one.createdAt;
                var api_name = one.api_name;
                var device = one.device;
                var userId = one.userId;


                data.id_start = func_lt(data.id_start,_id);
                data.id_end = func_gt(data.id_end,_id);

                var map1 = data.user_map[userId];
                if(!map1){
                    map1={count:0, start_time:null, end_time:null};
                    data.user_map[userId] = map1;
                }

                map1.count++;
                map1.start_time = func_lt(map1.start_time, createdAt);
                map1.end_time = func_gt(map1.end_time, createdAt);

                var map2 = data.api_map[api_name];
                if(!map2){
                    map2={count:0, start_time:null, end_time:null};
                    data.api_map[api_name] = map2;
                }
                map2.count++;
                map2.start_time = func_lt(map2.start_time, createdAt);
                map2.end_time = func_gt(map2.end_time, createdAt);

                if(data.device.indexOf(device) <0){
                    data.device.push(device);
                }
            }

            return callback(null, data);
        }
        // 时间转换成ObjId
        function timeToObjId( time ) {
            var t = new Date(time);
            t = t.getTime()/1000; // 转换成秒数
            return t.toString(16)+'0000000000000000'; // 转换成16进制的字符串，再加补齐16个0
        }

        // 对一天的数据分页处理
        var objIdTimeFrom = timeToObjId(startDate );
        var objIdTimeTo = timeToObjId( endDate );
        var c = {'createdAt': {
                            '$gt': ( startDate ),
                            '$lt': ( endDate )
                }};
        MAPILogModel.find(c).count().exec(function(error, count){
            if (error) {
                console.log('api app.js ins Err: '+error);
            }

            var pageSize = 1000; // 分页处理
            var pageCount = Math.ceil((count+pageSize)/pageSize)-1;
            //pageCount=1; // for test

            var asyncFuncs = [];
            for (var i=0;i<pageCount;i++) {
                asyncFuncs.push((function (pageNum) {
                    return function (asyncCallback) {
                        MAPILogModel.find(c).skip(pageSize*pageNum).limit(pageSize).exec(function(error, items){
                            if (error) {
                                console.log('api app.js ins Err: '+insErr);
                                return asyncCallback(error, null);
                            }
                            processOnePage(items, function(error2, info){
                                return asyncCallback(error2, info);
                            });
                        });
                    };
                })(i)); // 利用闭包解决动态参数传递问题
            }
            async.series(asyncFuncs,function (err, results) {
                if(err || !results || results.length==0){
                    return callback(err, null);
                }
                // 删除旧数据
                var c = {
                    log_start:{'$gte':startDate},
                    log_end:{'$lte': endDate}
                };
                MAPILogSummaryModel.remove(c , function(error3, insRet){
                    if (error3) {
                        console.log('api app.js ins Err: '+error3);

                        return callback(error3, null);
                    }

                    // 添加新数据
                    var summary={
                        // _id:ObjectId,     // default id
                        log_start:null,      // 开始时间(每个小时一次统计)
                        log_end:null,        // 结束时间
                        id_start:null,   // 开始id
                        id_end:null,     // 结束id
                        online_time_min:null,  // 最小在线时间
                        online_time_max:null,  // 最大在线时间
                        online_user_count:null, // 活跃用户数
                        count:null            // 使用总次数
                    }
                    var ids = {};
                    for(var i=0;i<results.length;i++){
                        var one = results[i];
                        var uids = func_enum(one.user_map);
                        var tmax = 0, tmin=0;
                        for(var k=0;k<uids.length;k++){
                            var uid = uids[k];
                            var uinfo = one.user_map[uid];
                            var t = func_minus_time(uinfo.start_time,uinfo.end_time);
                            tmax = func_gt(tmax, t);
                            tmin = func_lt(tmin, t);

                            ids[uid]=1; //记录userId
                        }
                        summary.online_time_min = func_lt( summary.online_time_min,tmin);
                        summary.online_time_max = func_gt( summary.online_time_max,tmax);

                        summary.id_start=func_lt(summary.id_start, one.id_start);
                        summary.id_end=func_gt(summary.id_end, one.id_end);
                    }
                    summary.online_user_count=func_enum(ids).length; // 总用户数量
                    summary.count = count;
                    summary.log_start = startDate;
                    summary.log_end = endDate;

                    // 记录到MongoDB中
                    var model = MAPILogSummaryModel(summary);
                    MAPILogSummaryModel.create(model, function(error3, insRet){
                        if (error3) {
                            console.log('api app.js ins Err: '+error3);

                            return callback(error3, null);
                        }
                        return callback(null, summary);
                    });
                });
            });
        });
    };

    //------------------------------------------------------------------
    /**
     * js时间对象的格式化;
     * 参数：d：DateTime对象
     * 参数：eg:format="yyyy-MM-dd hh:mm:ss";
     */
    summaryUtil.formatDate =  function  (date,format) {
        var o = {
            "M+": date.getMonth() + 1,  //month
            "d+": date.getDate(),     //day
            "h+": date.getHours(),    //hour
            "m+": date.getMinutes(),  //minute
            "s+": date.getSeconds(), //second
            "q+": Math.floor((date.getMonth() + 3) / 3),  //quarter
            "S": date.getMilliseconds() //millisecond
        }
        var week=["星期日","星期一","星期二","星期三","星期四","星期五","星期六"];
        if (/(y+)/.test(format)) {
            format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
        }
        if (/(w+)/.test(format)){
            format = format.replace(RegExp.$1, week[date.getDay()]);
        }
        for (var k in o) {
            if (new RegExp("(" + k + ")").test(format)) {
                format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
            }
        }
        return format;
    }
    //------------------------------------------------------------------
    /**
     * js中更改日期
     * 参数：d，日期 '2015-08-01 00:00:00'
     * 参数：part，y年， m月， d日， h小时， n分钟，s秒
     * 参数：value，增量
     */
    summaryUtil.addDate =  function  (date, part, value) {
        var d = new Date(date);
        value *= 1;
        if (isNaN(value)) {
            value = 0;
        }
        switch (part) {
            case "y":
                d.setFullYear(d.getFullYear() + value);
                break;
            case "m":
                d.setMonth(d.getMonth() + value);
                break;
            case "d":
                d.setDate(d.getDate() + value);
                break;
            case "h":
                d.setHours(d.getHours() + value);
                break;
            case "n":
                d.setMinutes(d.getMinutes() + value);
                break;
            case "s":
                d.setSeconds(d.getSeconds() + value);
                break;
            default:

        }
        return summaryUtil.formatDate(d, "yyyy-MM-dd hh:mm:ss");
    }


    //------------------------------------------------------------------
    // 功能：从APILog统计一天所有的数据
    // 参数：date，一天开始时间，例如：'2015-08-12 00:00:00'
    summaryUtil.summaryOneDayFromAPILog = function(date, callback) {
        // 拆分成24小时
        var asyncFuncs = [];
        for(var i=0;i<24; i++){
            var h0 = summaryUtil.addDate(date, 'h',i);
            var h1 = summaryUtil.addDate(date, 'h',i+1);
            asyncFuncs.push((function (startDate, endDate) {
                return function (asyncCallback) {
                    summaryUtil.summaryOnePeriodFromAPILog(startDate, endDate, function(error, infos){
                        return asyncCallback(null, infos);
                    })
                };
            })(h0, h1)); // 利用闭包解决动态参数传递问题
        }
        async.series(asyncFuncs,function (err, results) {
            if (err || !results || results.length == 0) {
                return callback(err, null);
            }
            return callback(null, results);
        });
    };

    //------------------------------------------------------------------
    // 功能：从APILog统计一个月所有的数据
    // 参数：date，一个月开始时间，例如：'2015-08-01 00:00:00'
    summaryUtil.summaryOneMonthFromAPILog = function(date, callback) {
        // 拆分成31天
        var asyncFuncs = [];
        for(var i=0;i<31; i++){
            var h0 = summaryUtil.addDate(date, 'd',i);
            var h1 = summaryUtil.addDate(date, 'd',i+1);
            asyncFuncs.push((function (startDate, endDate) {
                return function (asyncCallback) {
                    summaryUtil.summaryOneDayFromAPILog(startDate, function(error, infos){
                        return asyncCallback(null, infos);
                    })
                };
            })(h0, h1)); // 利用闭包解决动态参数传递问题
        }
        async.series(asyncFuncs,function (err, results) {
            if (err || !results || results.length == 0) {
                return callback(err, null);
            }
            return callback(null, results);
        });
    };


    //------------------------------------------------------------------
    // 功能：从APILog统计一年所有的数据
    // 参数：date，一年开始时间，例如：'2015-01-01 00:00:00'
    summaryUtil.summaryOneYearFromAPILog = function(date, callback) {
        // 拆分成12个月
        var asyncFuncs = [];
        for(var i=0;i<12; i++){
            var h0 = summaryUtil.addDate(date, 'm',i);
            var h1 = summaryUtil.addDate(date, 'm',i+1);
            asyncFuncs.push((function (startDate, endDate) {
                return function (asyncCallback) {
                    summaryUtil.summaryOneMonthFromAPILog(startDate, function(error, infos){
                        return asyncCallback(null, infos);
                    })
                };
            })(h0, h1)); // 利用闭包解决动态参数传递问题
        }
        async.series(asyncFuncs,function (err, results) {
            if (err || !results || results.length == 0) {
                return callback(err, null);
            }
            return callback(null, results);
        });
    };

    //------------------------------------------------------------------
    // 功能：从APILog统计未统计的数据
    summaryUtil.summaryUnsummaryDataFromAPILog = function(callback) {

    };

    //------------------------------------------------------------------
    // 功能：从从APILogSummary中获取数据
    // 参数：startTime，开始时间，例如：'2015-08-01 00:00:00'
    // 参数：endTime，结束时间，例如：'2015-08-01 01:00:00'
    // 参数：callabck：
    //          error:
    //          data:{
    //                  online_time_min:
    //                  online_time_max:
    //                  online_user_count:
    //                  count:1000
    //              }
    summaryUtil.getInfoFromSummary = function(startDate, endDate, callback) {
        //
        var c = {'log_start': {
            '$gte': ( startDate ),
            '$lt': ( endDate )
        }};
        MAPILogSummaryModel.find(c).exec(function(error, items) {
            if (error || !items || items.length==0) {
                console.log('api app.js ins Err: ' + error);
                return callback(error, null);
            }
            var data = {
                online_time_min:0,
                online_time_max:0,
                online_user_count:0,
                count:0
            };
            for(var i=0;i<items.length;i++){
                var one = items[i];
                data.online_time_min = one. online_time_min;
                data.online_time_max = one. online_time_max;
                data.online_user_count += one. online_user_count;
                data.count += one. count;
            }

            return callback(null, data)

        });

    };


//--------------------------------------------------------------------------------------------
    return summaryUtil;
})();
module.exports = summaryUtil;